package com.tamartech.greendb.dao;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;

import com.tamartech.greendb.data.Address;
import com.tamartech.greendb.data.ElectoralRoll;
import com.tamartech.greendb.data.ElectoralRollEntry;


public class ElectoralRollEntryDAO extends DAO
{
   public ElectoralRollEntry save (ElectoralRollEntry a) 
         throws Exception
   {
      try
      {
         begin();
         getSession().save(a);
         commit();
         return a;
      }
      catch (HibernateException e)
      {
         rollback();
         throw new Exception("Could not create ElectoralRollEntry", e);
      }
   }


//   public void update(ElectoralRollEntry a) throws Exception 
//   {
//      try 
//      {
//         begin();
//         getSession().update(a);
////         getSession().save(a);
//         commit();
//      } 
//      catch (HibernateException e) 
//      {
//         rollback();
//         throw new Exception("Could not save ElectoralRollEntry", e);
//      }
//   }

   public ElectoralRollEntry get (Long id) throws Exception 
   {
      try 
      {
         begin();
         ElectoralRollEntry a = (ElectoralRollEntry) getSession().load(ElectoralRollEntry.class, id);
         commit();
         return a;
      } 
      catch (HibernateException e) 
      {
         rollback();
         throw new Exception("Could not obtain ElectoralRollEntry " + id, e);
      }
   }
   
   public List<ElectoralRollEntry> findByAddress (Address address) throws Exception 
   {
      // ?? This seems like a very laborious query. Can I optimise somehow?
      try 
      {
         begin();
         Query q = getSession().createQuery("from ElectoralRollEntry where address = :address ");
         q.setEntity ("address", address);

         List<ElectoralRollEntry> found =  q.list();
         commit();
         return found;
      } 
      catch (HibernateException e) 
      {
         rollback();
         throw new Exception("Could not obtain ElectoralRollEntries for adddress: " + address, e);
      }
   }
   
    public ElectoralRollEntry findByReference(ElectoralRoll roll,
            String pollingDistrict, int voterNumber, Integer voterNumberSuffix)
            throws Exception
    {
        try
        {
            String queryStr = "from ElectoralRollEntry where electoralRoll = :roll and pollingDistrict = :pollingDistrict and voterNumber = :voterNumber and voterNumberSuffix is null";

            if (voterNumberSuffix != null)
            {
                queryStr = "from ElectoralRollEntry where electoralRoll = :roll and pollingDistrict = :pollingDistrict and voterNumber = :voterNumber and voterNumberSuffix = :voterNumberSuffix";

            }

            begin();
            Query q = getSession().createQuery(queryStr);
            q.setEntity("roll", roll);
            q.setString("pollingDistrict", pollingDistrict);
            q.setInteger("voterNumber", voterNumber);

            if (voterNumberSuffix != null)
            {
                q.setInteger("voterNumberSuffix", voterNumberSuffix);
            }
            
            ElectoralRollEntry e = (ElectoralRollEntry) q.uniqueResult();
            commit();
            return e;
        }
        catch (HibernateException e)
        {
            rollback();
            throw new Exception("Could not obtain ElectoralRollEntry. Roll: " + roll + 
                                ". Polling District: " + pollingDistrict + 
                                ". voterNumber: " + voterNumber +
                                ". voterNumberSuffix: " + voterNumberSuffix, e);
        }
    }
   
/*
   public ElectoralRollEntry get (String name) throws Exception 
   {
      try 
      {
         begin();
         Query q = getSession().createQuery("from ElectoralRollEntry where name = :name");
         q.setString ("name", name);
         ElectoralRollEntry a = (ElectoralRollEntry) q.uniqueResult();
         commit();
         return a;
      } 
      catch (HibernateException e) 
      {
         rollback();
         throw new Exception("Could not obtain ElectoralRollEntry " + name, e);
      }
   }
*/
   @SuppressWarnings("unchecked")
   public List<ElectoralRollEntry> list() throws Exception 
   {
      try 
      {
         begin();
         Query q = getSession().createQuery("from ElectoralRollEntry");
         List<ElectoralRollEntry> list = q.list();
         commit();
         return list;
      } 
      catch (HibernateException e) 
      {
         rollback();
         throw new Exception("Could not list the ElectoralRollEntrys", e);
      }
   }

   @SuppressWarnings("unchecked")
   public List<ElectoralRollEntry> listByRoll (ElectoralRoll roll) throws Exception 
   {
      try 
      {
         begin();
         Query q = getSession().createQuery("from ElectoralRollEntry where electoralRoll = :electoralRoll ");
         q.setEntity ("electoralRoll", roll);

         List<ElectoralRollEntry> found =  q.list();
         commit();
         return found;
      } 
      catch (HibernateException e) 
      {
         rollback();
         throw new Exception("Could not list the ElectoralRollEntrys", e);
      }
   }

   @SuppressWarnings("unchecked")
   public List<ElectoralRollEntry> listByPollingDistrict (ElectoralRoll roll, String pollingDistrict) throws Exception 
   {
      try 
      {
         begin();
         Query q = getSession().createQuery("from ElectoralRollEntry where electoralRoll = :electoralRoll and pollingDistrict = :pollingDistrict");
         q.setEntity ("electoralRoll", roll);
         q.setString ("pollingDistrict", pollingDistrict);

         List<ElectoralRollEntry> found =  q.list();
         commit();
         return found;
      } 
      catch (HibernateException e) 
      {
         rollback();
         throw new Exception("Could not list the ElectoralRollEntrys", e);
      }
   }

   
   public void delete(ElectoralRollEntry a)
      throws Exception
   {
      try
      {
         begin();
         getSession().delete(a);
         commit();
      }
      catch (HibernateException e)
      {
         rollback();
         throw new Exception("Could not delete ElectoralRollEntry", e);
      }
   }
}
